package com.xh.bussiness.resource.util;

import com.aspose.words.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.resource.model.Material;
import com.xh.bussiness.system.model.Icon;
import com.xh.bussiness.system.service.IIconService;
import com.xh.bussiness.teachbook.util.TeachingBookUtils;
import com.xh.bussiness.tiku.bean.dto.QuestionDto;
import com.xh.bussiness.tiku.constant.PaperConstant;
import com.xh.bussiness.tiku.util.ExportQuestionUtils;
import com.xh.core.util.FileUtils;
import com.xh.core.util.HandleNodeChangingFontChangerMaterial;
import com.xh.core.util.OfficeUtils;
import com.xh.core.util.StringUtils;
import com.xh.one2one.knowledgeSystem.service.IKnowledgeManagerService;
import com.xh.one2one.teachHandout.bean.dto.HandoutContentDto;
import com.xh.one2one.teachHandout.bean.dto.HandoutNodeDto;
import com.xh.one2one.teachHandout.bean.request.HandoutNodeRequest;
import com.xh.one2one.teachHandout.service.IHandoutNodeService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 讲义下载工具类
 *
 * @author: 赵文博
 * @date: 2021/5/11
 */
@Component
public class MaterialUtils {

    @Autowired
    private IHandoutNodeService handoutNodeService;
    @Autowired
    private IKnowledgeManagerService knowledgeManagerService;
    @Autowired
    private IIconService iIconService;


    private static IHandoutNodeService handoutNodeService1;
    private static IKnowledgeManagerService knowledgeManagerService1;
    private static IIconService iIconService1;

    @PostConstruct
    public void init() {
        handoutNodeService1 = handoutNodeService;
        knowledgeManagerService1 = knowledgeManagerService;
        iIconService1 = iIconService;
    }

    /**
     * 下载讲义，先生成讲义，并把知识元用占位符替代，再生成知识元文档，最后合并两个文档
     *
     * @param material
     * @param request
     * @param fileType
     * @return java.lang.String
     * @author 赵文博
     * @date 2021/5/19 10:09
     **/
    public static String exportMaterial(Material material, HttpServletRequest request, String fileType, Integer downType) throws Exception {
        StringBuffer url = request.getRequestURL();
        String rootPath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
        String paperTemplatePath = TeachingBookUtils.class.getResource("/").getFile() + "templates/material/MaterialTemplate.docx";
        ;
        if (System.getProperty("file.separator").equals("\\")) {
            paperTemplatePath = paperTemplatePath.substring(1);
        }

        //实例化word模板
        Document doc = new Document(paperTemplatePath);
        // insertHtml 字体处理
        doc.setNodeChangingCallback(new HandleNodeChangingFontChangerMaterial(10.5));
        //处理html内容
        doc.getRange().replace("«MATERIALNAME»", "@@" + material.getFileName() + "@@", new FindReplaceOptions());

        DocumentBuilder builder = new DocumentBuilder(doc);
        builder.moveToDocumentEnd();
        // 设置左右边距
        builder.getPageSetup().setLeftMargin(65);
        builder.getPageSetup().setRightMargin(65);
        // 设置行间距
        builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE);
        builder.getParagraphFormat().setLineSpacing(18);

        //组装讲义内容
        HandoutNodeRequest bean = new HandoutNodeRequest();
        bean.setHandoutId(material.getId());
        List<HandoutNodeDto> handoutNodeDTOS = handoutNodeService1.downHandoutNode(bean);
        questionNumber(handoutNodeDTOS);
        List<String> fileNames = writer(handoutNodeDTOS, material.getSubject(), builder, request, rootPath, downType);

        String exportPath = request.getSession().getServletContext().getRealPath("/") + "test/export/paper/" + FileUtils.createRandomFilename() + ".doc";
        FileUtils.createFileDirectory(exportPath);
        //定位段落中图片位置垂直居中显示
        double lineHeight = -3.5;
        NodeCollection childNodes = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < childNodes.getCount(); i++) {
            //删除空行
            Paragraph paragraph = (Paragraph) childNodes.get(i);
            if (!paragraph.hasChildNodes()) {
                paragraph.remove();
            }
            NodeCollection collection = paragraph.getChildNodes(NodeType.SHAPE, true);
            for (int j = 0; j < collection.getCount(); j++) {
                Shape shape = (Shape) collection.get(j);
                shape.getFont().setPosition(-shape.getHeight() / 2 - lineHeight);
            }
        }
        doc.save(exportPath, SaveFormat.DOCX);


        //组装知识元
        if (fileNames != null && fileNames.size() > 0) {
            Map<String, String> mergeFiles = new LinkedHashMap<>();
            int i = 0;
            for (HandoutNodeDto nodeVO : handoutNodeDTOS) {
                if (nodeVO.getType() == 3) {
                    String fileName = fileNames.get(i);
                    String knowledgePath = writerKnowledge(nodeVO, request, material.getSubject(), fileName, downType);
                    if (!StringUtils.isEmpty(fileName) && !StringUtils.isEmpty(knowledgePath)) {
                        mergeFiles.put(fileName, knowledgePath);
                    }
                    i++;
                }
            }
            //合并文档
            if (!mergeFiles.isEmpty()) {
                String newExportPath = request.getSession().getServletContext().getRealPath("/") + "export/paper/" + FileUtils.createRandomFilename() + ".doc";
                OfficeUtils.wordsInsert(exportPath, newExportPath, mergeFiles);
                //删除原文件
                FileUtils.delFile(exportPath);
                exportPath = newExportPath;
            }
        }
        //下载PDF
        if ("pdf".equals(fileType)) {
            String pdfPath = exportPath.substring(0, exportPath.length() - 3) + "pdf";
            OfficeUtils.word2pdf(exportPath, pdfPath, null);
            return pdfPath;
        }
        return exportPath;
    }

    /**
     * 生成讲义
     *
     * @param handoutNodeVOS
     * @param subject
     * @param builder
     * @param rootPath
     * @return java.util.List<java.lang.String>
     * @author 赵文博
     * @date 2021/5/15 15:59
     **/
    private static List<String> writer(List<HandoutNodeDto> handoutNodeVOS, String subject, DocumentBuilder builder, HttpServletRequest request, String rootPath, Integer downType) throws Exception {
        List<String> fileNames = new ArrayList<>();
        for (HandoutNodeDto nodeVO : handoutNodeVOS) {
            Integer type = nodeVO.getType();
            String fileName = FileUtils.createRandomFilename();
            switch (type) {
//                1、标题，2、文本   3 知识元  4 试题   5 试卷 6 学生错题 7  思维导图   8 变式题
                case 1:
                    builder.insertHtml(writerHandoutTitleIcon(nodeVO.getCssType(), nodeVO.getContent(), request));
                    builder.writeln();
                    break;//标题
//                case 1:builder.insertHtml(nodeVO.getContent());builder.writeln();break;
                case 2:
                    builder.insertHtml(deleteOpacityIsZeroImg(nodeVO.getContent()));
                    builder.writeln();
                    break;//文本
                case 3:
                    builder.insertHtml("<" + fileName + ">");
                    fileNames.add(fileName);
                    break;//知识元
                case 4:
                case 8:
                case 9:
                    question(nodeVO.getQuestion(), nodeVO.getEmptyLine(), subject, builder, rootPath, downType, null);
                    break;//练习题
            }
        }
        return fileNames;
    }

    private static void question(QuestionDto questionDto, Integer emptyLine, String subject, DocumentBuilder builder, String rootPath, Integer downType, Integer questionType) throws Exception {
//        questionDto.setTitle(deleteBr(questionDto.getTitle()));
        if(questionDto == null){
            return;
        }
//        String quesNum = "";
//        if(questionType != null){
//            if (questionType == 4) {
//                quesNum = "<span style='color: #1AAFA7'>试题" + questionDto.getQuestionNo() + "：</span>";
//            } else if (questionType == 8) {
//                quesNum = "<span style='color: #1AAFA7'>变式" + questionDto.getQuestionNo() + "：</span>";
//            } else if (questionType == 9) {
//                quesNum = "<span style='color: #1AAFA7'>练习" + questionDto.getQuestionNo() + "：</span>";
//            }
//        }
        questionDto.setTitle(deleteBr(questionDto.getTitle()));
        questionDto.setOrderNo(0);
        //downType 1,教师 2,学生 3,解析版
        if (downType.equals(PaperConstant.PAPER_TYPE.TEACHER)) {
            ExportQuestionUtils.createMaterialQuestion(emptyLine, subject, rootPath, questionDto, builder, true, true, true, false);
        } else if (downType.equals(PaperConstant.PAPER_TYPE.STUDENT)) {
            ExportQuestionUtils.createMaterialQuestion(emptyLine, subject, rootPath, questionDto, builder, true, false, false, false);

        } else if (downType.equals(PaperConstant.PAPER_TYPE.ANALYSIS)) {
            ExportQuestionUtils.createMaterialQuestion(emptyLine, subject, rootPath, questionDto, builder, false, true, true, false);

        } else {
            //没有类型，按照学生版解析
            ExportQuestionUtils.createMaterialQuestion(emptyLine, subject, rootPath, questionDto, builder, true, false, false, false);
        }
    }

    /**
     * 写入知识元
     *
     * @param request
     * @return java.lang.String
     * @author 赵文博
     * @date 2021/5/14 15:18
     **/
    public static String writerKnowledge(HandoutNodeDto nodeVO, HttpServletRequest request, String subject, String fileName, Integer downType) throws Exception {
        StringBuffer url = request.getRequestURL();
        String rootPath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
        // 获取教师上传的模板
        String paperTemplatePath = TeachingBookUtils.class.getResource("/").getFile() + "templates/material/knowledgeTemplate.docx";
        if (System.getProperty("file.separator").equals("\\")) {
            paperTemplatePath = paperTemplatePath.substring(1);
        }
        //实例化word模板
        Document doc = new Document(paperTemplatePath);
        // insertHtml 字体处理
        doc.setNodeChangingCallback(new HandleNodeChangingFontChangerMaterial(10.5));
        //设置标题
        doc.getRange().replace("«knowledgeName»", "@@" + nodeVO.getContent() + "@@", new FindReplaceOptions());

        DocumentBuilder builder = new DocumentBuilder(doc);
        builder.moveToDocumentEnd();
        // 设置左右边距
        builder.getPageSetup().setLeftMargin(65);
        builder.getPageSetup().setRightMargin(65);
        // 设置行间距
        builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE);
        builder.getParagraphFormat().setLineSpacing(18);
        //组装知识元内容
        for (HandoutContentDto child : nodeVO.getChild()) {
            Integer type = child.getType();
            switch (type) {
                case 1:
                    builder.insertHtml(writerHandoutTitleIcon(child.getCssType(), child.getContent(), request));
                    builder.writeln();
                    break;
//                case 2:builder.insertHtml(deleteOpacityIsZeroImg(child.getContent()));builder.writeln();break;//文本
                case 2:
                    String html = deleteOpacityIsZeroImg(child.getContent());
                    builder.insertHtml(html);
                    builder.writeln();
                    break;//文本
                case 4:
                case 8:
                case 9:
                    question(child.getQuestion(), nodeVO.getEmptyLine(), subject, builder, rootPath,downType, type);
                    break;//变式题
            }
        }


        String exportPath = request.getSession().getServletContext().getRealPath("/") + "test/export/paper/" + fileName + ".doc";
        FileUtils.createFileDirectory(exportPath);
        //定位段落中图片位置垂直居中显示
        double lineHeight = -3.5;
        NodeCollection childNodes = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < childNodes.getCount(); i++) {
            //删除空行
            Paragraph paragraph = (Paragraph) childNodes.get(i);
            if (!paragraph.hasChildNodes()) {
                paragraph.remove();
            }
            NodeCollection collection = paragraph.getChildNodes(NodeType.SHAPE, true);
            for (int j = 0; j < collection.getCount(); j++) {
                Shape shape = (Shape) collection.get(j);
                shape.getFont().setPosition(-shape.getHeight() / 2 - lineHeight);
            }
        }
        doc.save(exportPath, SaveFormat.DOCX);
        return exportPath;
    }


    /**
     * 生成题号
     *
     * @param handoutNodeDTOS
     * @return void
     * @author 赵文博
     * @date 2021/5/15 15:58
     **/
    private static void questionNumber(List<HandoutNodeDto> handoutNodeDTOS) {
        Integer number = 1;
        Integer variantNumber = 1; //变式题号
        Integer practiceNumber = 1; //变式题号
        for (HandoutNodeDto nodeDto : handoutNodeDTOS) {
            //类型(1、标题，2、文本   3 知识元  4 试题   7  思维导图   8 变式题 )
            Integer type = nodeDto.getType();
            if (type == 3) {
                number = knowledgeNumber(number, nodeDto.getChild());
                variantNumber = 1;
            } else if (type == 4) {
                exampleNumber(number, nodeDto);
                number++;
                variantNumber = 1;
            } else if (type == 8) {
                questionVariantNumber(variantNumber, number, nodeDto);
                variantNumber++;
            } else if (type == 9) {
                questionPracticeNumber(practiceNumber, number, nodeDto);
                practiceNumber++;
            }
        }
    }

    /**
     * 例题题号
     *
     * @param number
     * @param nodeDto
     * @return void
     * @author 赵文博
     * @date 2021/5/15 14:04
     **/
    private static void exampleNumber(Integer number, HandoutNodeDto nodeDto) {
        String numberStr = "<span style='color: #0174DF;'>例题" + number + ":</span>";
        String title = nodeDto.getQuestion().getTitle();
        nodeDto.getQuestion().setTitle(numberStr + title);
    }

    /**
     * 变式题题号
     *
     * @param variantNumber
     * @param number
     * @param nodeDto
     * @return void
     * @author 赵文博
     * @date 2021/5/15 15:58
     **/
    private static void questionVariantNumber(Integer variantNumber, Integer number, HandoutNodeDto nodeDto) {
        String numberStr = "<span style='color: #0174DF;'>变式" + (--number) + "-" + variantNumber + ":</span>";
        String title = nodeDto.getQuestion().getTitle();
        nodeDto.getQuestion().setTitle(numberStr + title);
    }

    private static void questionPracticeNumber(Integer variantNumber, Integer number, HandoutNodeDto nodeDto) {
        String numberStr = "<span style='color: #0174DF;'>练习" + variantNumber + "：</span>";
        String title = nodeDto.getQuestion().getTitle();
        nodeDto.getQuestion().setTitle(numberStr + title);
    }

    /**
     * 知识元变式题题号
     *
     * @param variantNumber
     * @param number
     * @param nodeDto
     * @return void
     * @author 赵文博
     * @date 2021/5/17 10:39
     **/
    private static void questionVariantNumber(Integer variantNumber, Integer number, HandoutContentDto nodeDto) {
        String numberStr = "<span style='color: #0174DF;'>变式" + (--number) + "-" + variantNumber + ":</span>";
        String title = nodeDto.getQuestion().getTitle();
        nodeDto.getQuestion().setTitle(numberStr + title);
    }
    private static void questionPracticeNumber(Integer variantNumber, Integer number, HandoutContentDto nodeDto) {
        String numberStr = "<span style='color: #0174DF;'>练习" + variantNumber + ":</span>";
        String title = nodeDto.getQuestion().getTitle();
        nodeDto.getQuestion().setTitle(numberStr + title);
    }
    /**
     * 知识元题号
     *
     * @param number
     * @param childes
     * @return java.lang.Integer
     * @author 赵文博
     * @date 2021/5/15 15:58
     **/
    private static Integer knowledgeNumber(Integer number, List<HandoutContentDto> childes) {
        Integer variantNumber = 1;
        Integer practiceNumber = 1;
        for (HandoutContentDto child : childes) {
            //类型(1、标题，2、文本   3 知识元  4 试题   5 试卷 6 学生错题 7  思维导图   8 变式题)
            Integer type = child.getType();
            switch (type) {
                case 4:
                    child.getQuestion().setTitle("<span style='color: #0174DF;'>例题" + number + ":</span>"
                            + child.getQuestion().getTitle());
                    number++;
                    variantNumber = 1;
                    break;
                case 8:
                    questionVariantNumber(variantNumber, number, child);
                    variantNumber++;
                    break;
                case 9:
                    questionPracticeNumber(practiceNumber, number, child);
                    practiceNumber++;
                    break;
            }
        }
        return number;
    }

    /**
     * 删除透明度为0的图片
     *
     * @param html
     * @return java.lang.String
     * @author 赵文博
     * @date 2021/6/3 10:17
     **/
    private static String deleteOpacityIsZeroImg(String html) {
        org.jsoup.nodes.Document document = Jsoup.parseBodyFragment(html);
        //div会造成下面的行首行缩进
//        Elements divs = document.select("div");
//        if(divs.size()>0){
////            divs.tagName("span");
//            divs.tagName("p");
//        }
        Elements opacity = document.select("img[style]");
        if (opacity.size() > 0) {
            for (Element element : opacity) {
                if (element.attr("style").contains("opacity: 0")) {
                    System.out.println(element);
                    element.remove();
                }
            }
            return document.body().children().toString();
        }
        return html;
    }

    /**
     * 处理知识元的标题图标
     *
     * @param child
     * @return void
     * @author 赵文博
     * @date 2021/6/7 17:17
     **/
    private static String writerTitleIcon(HandoutContentDto child, String templateId, HttpServletRequest request) {
        StringBuilder iconImg = new StringBuilder();
        if (child.getCssType() != null) {
            QueryWrapper<Icon> qwIcon = new QueryWrapper<>();
            qwIcon.eq("css_type", child.getCssType());
            qwIcon.eq("template_id", templateId);
            Icon icon = iIconService1.selectFirst(qwIcon);
            if (icon != null) {
                String iconPath = request.getSession().getServletContext().getRealPath("/") + icon.getFilePath().substring(1, icon.getFilePath().length());
                iconImg = iconImg.append("<img src= '" + iconPath + "' height='40' width='40' />&nbsp;&nbsp;");

            }
        }
        String htmlChinese = getChinese(child.getContent());
        if (StringUtils.isNotEmpty(htmlChinese)) {
            iconImg = iconImg.append("<span style='font-family:微软雅黑; color:#1d7dd7'>$$" + htmlChinese + "$$</span>");
            return "<p style='float:left;'>" + iconImg.toString() + "</p>";
        }
        return "";
    }

    /**
     * 讲义图标
     *
     * @param nodeVO
     * @param request
     * @return java.lang.String
     * @author 赵文博
     * @date 2021/6/25 16:18
     **/
    private static String writerHandoutTitleIcon(HandoutNodeDto nodeVO, HttpServletRequest request) {
        StringBuilder iconImg = new StringBuilder();
        if (nodeVO.getCssType() != null) {
            QueryWrapper<Icon> qwIcon = new QueryWrapper<>();
            qwIcon.eq("css_type", nodeVO.getCssType());
            qwIcon.eq("type", 2);
            Icon icon = iIconService1.selectFirst(qwIcon);
            if (icon != null) {
                String iconPath = request.getSession().getServletContext().getRealPath("/") + icon.getFilePath().substring(1, icon.getFilePath().length());
                iconImg = iconImg.append("<img src= '" + iconPath + "' height='40' width='40' />&nbsp;&nbsp;");

            }
        }
        String htmlChinese = getChinese(nodeVO.getContent());
        if (StringUtils.isNotEmpty(htmlChinese)) {
            iconImg = iconImg.append("<span style=' font-family:微软雅黑; color:#1d7dd7'>$$" + htmlChinese + "$$</span>");
            return "<p style='float:left;'>" + iconImg.toString() + "</p>";
        }
        return "";
    }

    /**
     * 讲义图标
     *
     * @return java.lang.String
     * @author 赵文博
     * @date 2021/6/25 16:18
     **/
    private static String writerHandoutTitleIcon(Integer cssType, String content, HttpServletRequest request) {
        if (null == cssType) {
            cssType = 4;
        }
        StringBuilder iconImg = new StringBuilder();
        QueryWrapper<Icon> qwIcon = new QueryWrapper<>();
        qwIcon.eq("css_type", cssType);
        qwIcon.eq("type", 2);
        Icon icon = iIconService1.selectFirst(qwIcon);
        if (icon != null) {
            String iconPath = request.getSession().getServletContext().getRealPath("/") + icon.getFilePath().substring(1, icon.getFilePath().length());
            iconImg = iconImg.append("<img src= '" + iconPath + "' height='40' width='40' />&nbsp;&nbsp;");

        }
        String htmlChinese = getChinese(content);
        if (StringUtils.isNotEmpty(htmlChinese)) {
            iconImg = iconImg.append("<span style=' font-family:微软雅黑; color:#1d7dd7'>$$" + htmlChinese + "$$</span>");
            return "<p style='float:left;'>" + iconImg.toString() + "</p>";
        }
        return "";
    }

    private static String deleteBr(String questionTitle) {
        String title = questionTitle.replaceAll("<br />", "");
        title = title.replaceAll("<br/>", "");
        return title;
    }

    private static String getChinese(String text) {
        org.jsoup.nodes.Document document = Jsoup.parseBodyFragment(text);
        return document.body().text();
    }
}
